package com.sky.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sky.constant.MessageConstant;
import com.sky.exception.OrderBusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class BaiduMapsUtil {
    /**
     * 校验配送范围
     */
    // 1. 注入店铺地址
    @Value("${sky.shop.address}")
    private String shopAddress;

    // 2. 注入百度地图AK（Access Key）
    @Value("${sky.shop.ak}")
    private String ak;

    // 3. 注入最大配送距离（假设以米为单位）
    @Value("${sky.shop.distance}")
    private Integer distance;


    public boolean checkOutOfRange(String address) {
        // 定义一个方法，输入参数为收货地址字符串，返回值为布尔类型，表示该地址是否超出配送范围。

        // 4. 创建一个Map用于存储API请求参数
        Map<String, String> paramMap = new HashMap<>();

        // 5. 设置店铺地址解析请求参数
        paramMap.put("address", this.shopAddress);
        paramMap.put("output", "json");  // 设置输出格式为JSON
        paramMap.put("ak", this.ak);      // 添加API AK作为请求参数

        // 6. 使用HttpClient工具发送GET请求到百度地图地址解析API
        String jsonStr = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3/", paramMap);
        // https://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号
        // &output=json&ak=您的ak&callback=showLocation

        // 7. 将返回的JSON字符串转换为JSONObject以便操作
        JSONObject jsonObject = JSON.parseObject(jsonStr);

        // 8. 检查请求状态码，若非0则表示地址解析失败，抛出业务异常
        if (!jsonObject.get("status").equals(0)) {
            throw new OrderBusinessException(MessageConstant.ADDRESS_PARSE_FAILED);
        }

        // 9. 从解析结果中提取店铺经纬度信息
        JSONObject locationJson = jsonObject.getJSONObject("result").getJSONObject("location");
        Object lng = locationJson.get("lng");  // 获取店铺经度
        Object lat = locationJson.get("lat");  // 获取店铺纬度

        // 10. 构造店铺坐标字符串
        String origin = lat + "," + lng;
        log.info("店铺的坐标：{}" , origin);
//----------------------------------------------------------------------------------------
        // 11. 重复上述过程，获取收货地址的经纬度信息
        paramMap.put("address", address);//覆盖
        jsonStr = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3/", paramMap);
        jsonObject = JSON.parseObject(jsonStr);

        // 检查请求状态码，同样处理地址解析失败的情况
        if (!jsonObject.get("status").equals(0)) {
            throw new OrderBusinessException(MessageConstant.ADDRESS_PARSE_FAILED);
        }

        locationJson = jsonObject.getJSONObject("result").getJSONObject("location");
        lng = locationJson.get("lng");  // 获取收货地址经度
        lat = locationJson.get("lat");  // 获取收货地址纬度

        // 12. 构造收货地址坐标字符串
        String destination = lat + "," + lng;
        log.info("收货地址的坐标：{}" , destination);
//-------------------------------------------------------------------------------------------
        // 13. 计算两点间的骑行距离，设置起始点和终点坐标
        paramMap.put("origin", origin);
        paramMap.put("destination", destination);
        jsonStr = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/riding", paramMap);
        jsonObject = JSON.parseObject(jsonStr);

        // 检查请求状态码，处理路径规划失败的情况
        if (!jsonObject.get("status").equals(0)) {
            throw new OrderBusinessException(MessageConstant.ADDRESS_PARSE_FAILED);
        }

        // 14. 从路径规划结果中提取骑行距离
        JSONArray routes = jsonObject.getJSONObject("result").getJSONArray("routes");
        Integer distanceFromApi = (Integer) routes.getJSONObject(0).get("distance");

        // 15. 输出计算得到的实际距离
        System.out.println("distance = " + distanceFromApi);

        // 16. 比较实际距离和预设最大配送距离，决定是否超出范围
        return distanceFromApi <= this.distance;
    }
}
